﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using RayD.App.SystemModule;
using RayD.Core;
using StackExchange.Profiling;
using System;
using System.Collections.Generic;
using System.Linq;

namespace RayD.App.Setup
{
    /// <summary>
    /// 授权过滤器
    /// </summary>
    public class ApiAuthorizeFilter : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            try
            {
                string appid = context.HttpContext.Request.Headers["appid"].ToString(); //商户Id
                string timestamp = context.HttpContext.Request.Headers["timestamp"].ToString(); //时间戳
                string sign = context.HttpContext.Request.Headers["sign"].ToString();   //签名
                //根据Appid获取AppSecret
                var app = ServiceContainer.Current.GetInstance<AppConfigApp>().GetEntityByAppId(appid);
                string appsecret = app?.B_AppSecret; //密钥
                if (!appsecret.IsEmpty())
                {
                    context.ActionArguments["company"] = app?.B_Authorizer; //向Action添加参数
                    #region 生成签名
                    string str = string.Empty;
                    string data = HttpContextHelper.GetRequestBody().ToJObject()["data"]?.ToString();
                    if (!data.IsEmpty())
                    {
                        data = DESEncrypt.Decrypt(data, appsecret); //DES解密
                        context.ActionArguments["json"] = data; //向Action添加参数
                        var jobj = data.ToJObject();
                        var dic = new Dictionary<string, string>();
                        foreach (var item in jobj)
                        {
                            dic.Add(item.Key, item.Value.ToString());
                        }
                        str = dic.Keys.OrderBy(c => c).Aggregate(string.Empty, (c, k) => c + dic[k]);
                    }
                    string tmpSign = Md5Helper.Encrypt($"{str}{appsecret}{timestamp}", 32).ToLower();//MD5小写32位加密 
                    #endregion
                    if (tmpSign == sign && timestamp.CheckNumber())
                    {
                        //校验时间戳（1分钟内）
                        DateTime dtTime = CommonHelper.ConvertTimestamp(timestamp.ToDouble());
                        double minutes = DateTime.Now.ToCstTime().Subtract(dtTime).TotalMinutes;
                        if (minutes > 1 || minutes < 0)
                        {
                            context.Result = new ContentResult()
                            {
                                ContentType = "application/json",
                                Content = new ResParameter { code = ResponseCode.fail, msg = "时间戳校验失败！", data = null }.ToJson(),
                                StatusCode = (int)ResponseCode.fail
                            };
                        }
                    }
                    else
                    {
                        context.Result = new ContentResult()
                        {
                            ContentType = "application/json",
                            Content = new ResParameter { code = ResponseCode.fail, msg = "签名校验失败！", data = null }.ToJson(),
                            StatusCode = (int)ResponseCode.fail
                        };
                    }
                }
                else
                {
                    context.Result = new ContentResult()
                    {
                        ContentType = "application/json",
                        Content = new ResParameter { code = ResponseCode.fail, msg = "商户Id校验失败！", data = null }.ToJson(),
                        StatusCode = (int)ResponseCode.fail
                    };
                }
            }
            catch (Exception ex)
            {
                context.Result = new ContentResult()
                {
                    ContentType = "application/json",
                    Content = new ResParameter { code = ResponseCode.exception, msg = "参数校验异常：" + ex.Message, data = null }.ToJson(),
                    StatusCode = (int)ResponseCode.exception
                };
            }
        }

    }
}
